home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 101-125 / scopedisk120 / mrcat / arpfilescan.c < prev    next >
C/C++ Source or Header  |  1995-03-19  |  5KB  |  167 lines

  1. /* ArpFileScan 
  2.  * Filename:    ArpFileScan
  3.  * Author:      Mark R. Rinfret
  4.  *
  5.  * ArpFileScan builds an expanded list of filenames from a filename argument list. 
  6.  * It is written to be entirely reentrant.
  7.  */
  8. #include <stdlib.h>
  9. #include <fcntl.h>
  10. #include <ctype.h>
  11. #include <string.h>
  12. #include <exec/types.h>
  13. #include <libraries/arpbase.h>
  14.  
  15. /*  The UserAnchor structure is used by ARP's FindFirst/FindNext routines. */
  16.  
  17. struct UserAnchor {
  18.     struct AnchorPath   ua_AP;
  19.     BYTE                moreMem[255];
  20. };
  21.  
  22. /*  The ListInfo structure tracks our filename list building process. */
  23.  
  24. typedef struct ListInfo {
  25.     char                    **theList;
  26.     int                     slotCount;          /* number of slots in the list. */
  27.     int                     entryCount;         /* number of slots filled */
  28.     struct DefaultTracker   *tracker;
  29.     struct UserAnchor       anchor;
  30.     } ListInfo;
  31.  
  32. /*  FUNCTION
  33.  *      StoreTracker - get the LastTracker value in register a1.
  34.  *
  35.  *  SYNOPSIS
  36.  *      struct DefaultTracker *StoreTracker(void);
  37.  *
  38.  *  DESCRIPTION
  39.  *      StoreTracker is a simple function written in assembly language to provide
  40.  *      access to the LastTracker item. This method was implemented because the
  41.  *      ARP method (via IoErr()) is unreliable at this time.
  42.  *
  43.  *      StoreTracker *MUST* be called immediately after a call to an ARP library
  44.  *      function which allocates a tracker. Otherwise, its results are unreliable.
  45.  */
  46.  
  47. struct DefaultTracker*
  48. StoreTracker(void)
  49. {
  50.     #asm
  51.        move.l  a1,d0   ; Simulate function result. Is this Lattice-compatible?
  52.     #endasm
  53. }
  54.  
  55. /*  FUNCTION
  56.  *      AddFile - add a filename to the filename list.
  57.  *
  58.  *  SYNOPSIS
  59.  *      static int AddFile(ListInfo *fileList, const char *theFile);
  60.  *
  61.  *  DESCRIPTION
  62.  *      AddFile attempts to add <theFile> to the filename list. The list will be
  63.  *      expanded if necessary. 
  64.  *
  65.  *      AddFile returns zero if successful or 1 on error.
  66.  */
  67.   
  68. static int
  69. AddFile(ListInfo *fileList, const char *theFile)
  70. {
  71.     char    *fName;                 /* for a copy of theFile */
  72.     char    **newList;
  73.     int     newCount;
  74.     size_t  newSize;
  75.     struct DefaultTracker *newTracker;
  76.  
  77.     if (fileList->entryCount >= fileList->slotCount) { /* Expand the list? */
  78.         newCount = fileList->slotCount + 50;
  79.         newSize = sizeof(char *) * newCount;
  80.         newList = ArpAlloc(newSize);
  81.         newTracker = StoreTracker();
  82.         if (newList == NULL) return 1;   /* Error! */
  83.         fileList->slotCount = newCount;
  84.         if (fileList->theList) {
  85.             /* Copy old stuff to new list. */
  86.             memcpy(newList, fileList->theList, newSize);
  87.             /* Dispose of the old list. */
  88.             FreeTrackedItem(fileList->tracker);
  89.             fileList->tracker = newTracker;
  90.         }
  91.         fileList->theList = newList;
  92.     }
  93.  
  94.     fName = ArpAlloc(strlen(theFile)+1);
  95.     if (! fName) return 1;
  96.     strcpy(fName, theFile);
  97.     fileList->theList[fileList->entryCount++] = fName;
  98.     return 0;
  99. }
  100.  
  101.  
  102. /*  FUNCTION
  103.  *      Compare - perform case-insensitive compare of two filename strings.
  104.  *
  105.  *  SYNOPSIS
  106.  *      static int Compare(const void *a, const void *b);
  107.  *
  108.  *  DESCRIPTION
  109.  *      Compare simply provides an interface between qsort() and a string
  110.  *      comparison routine. It returns the result of the string comparison.
  111.  */
  112.  
  113. static int
  114. Compare(const void *a, const void *b)
  115. {
  116.     return Strcmp(*(char **)a, *(char **)b);
  117. }
  118.  
  119.  
  120. /*  FUNCTION
  121.  *      ArpFileScan - scan, expand and optionally sort a file specification list.
  122.  *
  123.  *  SYNOPSIS
  124.  *      char **ArpFileScan(char **rawList, int rawCount, int *newCount; 
  125.  *                         int sortFiles);
  126.  *
  127.  *  DESCRIPTION
  128.  *      ArpFileScan treats each entry in <rawList> as a file specification and
  129.  *      attempts to expand it into multiple filenames. The number of entries
  130.  *      in <rawList> is defined by <rawCount>. If successful, ArpFileScan will
  131.  *      return a pointer to a new list of filenames, passing the number of entries
  132.  *      via <newCount>. If <sortFiles> is non-zero, the list will be sorted.
  133.  *
  134.  *      If ArpFileScan is unable to perform an allocation, NULL is returned.
  135.  */
  136.  
  137. char **
  138. ArpFileScan(char **rawList, int rawCount, int *newCount, int sortFiles)
  139. {
  140.     ListInfo    fileList;           /* Stack-based for reentrancy. */
  141.     int         rawIndex = 0;
  142.     int         result;
  143.     char        *rawName;
  144.     
  145.     fileList.theList = NULL;       /* Initialize the list structure. */
  146.     fileList.slotCount = 0;
  147.     fileList.entryCount = 0;
  148.     fileList.anchor.ua_AP.ap_StrLen = 255;  /* Want full path built. */
  149.     fileList.anchor.ua_AP.ap_BreakBits |=  (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D);
  150.  
  151.     while (rawIndex < rawCount) {
  152.         rawName = rawList[rawIndex++];
  153.         result = FindFirst(rawName, (struct AnchorPath *) &fileList.anchor);
  154.         while (result == 0) {
  155.             if (AddFile(&fileList, (const char *) &fileList.anchor.ua_AP.ap_Buf))
  156.                 return NULL;
  157.             result = FindNext((struct AnchorPath *) &fileList.anchor);
  158.         }
  159.     }
  160.  
  161.     *newCount = fileList.entryCount;
  162.     if (fileList.theList && sortFiles) {
  163.         qsort(fileList.theList, fileList.entryCount, sizeof(char *), Compare);
  164.     }
  165.     return fileList.theList;
  166. }
  167.